package com.lse_api.config.multipledatasources;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.github.pagehelper.PageHelper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 多数据源配置
 *
 * @author 祁雪
 */
@Configuration
@MapperScan(basePackages = "com.*.mapper")
public class DataSourceConfig {

    // 数据源1参数
    @Value("${spring.datasource.url}")
    private String jdbcUrl_me;
    @Value("${spring.datasource.username}")
    private String jdbcUsername_me;
    @Value("${spring.datasource.password}")
    private String jdbcPassword_me;

    // 数据源2参数
    @Value("${spring.lse.datasource.url}")
    private String jdbcUrl_lse;
    @Value("${spring.lse.datasource.username}")
    private String jdbcUsername_lse;
    @Value("${spring.lse.datasource.password}")
    private String jdbcPassword_lse;

    // 公共参数
    @Value("${spring.datasource.driver-class-name}")
    private String jdbcDriver;

    @Value("${spring.datasource.initialSize}")
    private String initialSize;

    @Value("${spring.datasource.minIdle}")
    private String minIdle;

    @Value("${spring.datasource.maxActive}")
    private String maxActive;

    @Value("${spring.datasource.maxWait}")
    private String maxWait;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private String timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private String minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    @Value("${spring.datasource.testWhileIdle}")
    private String testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")
    private String testOnBorrow;

    @Value("${spring.datasource.testOnBorrow}")
    private String testOnReturn;

    @Value("${spring.datasource.poolPreparedStatements}")
    private String poolPreparedStatements;

    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private String maxPoolPreparedStatementPerConnectionSize;

    @Value("${spring.datasource.connectionProperties}")
    private String connectionProperties;

    @Value("${mybatis-plus.mapper-locations}")
    private String xmlPath;

    // 数据源1
    @Bean(name = "dataSource_me")
    public DataSource dataSource_me() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(jdbcDriver);
        druidDataSource.setUrl(jdbcUrl_me);
        druidDataSource.setUsername(jdbcUsername_me);
        druidDataSource.setPassword(jdbcPassword_me);
        setDataSourceParams(druidDataSource);
        return druidDataSource;
    }

    // 数据源2
    @Bean(name = "dataSource_lse")
    public DataSource dataSource_lse() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(jdbcDriver);
        druidDataSource.setUrl(jdbcUrl_lse);
        druidDataSource.setUsername(jdbcUsername_lse);
        druidDataSource.setPassword(jdbcPassword_lse);
        setDataSourceParams(druidDataSource);
        return druidDataSource;
    }

    // 动态数据源
    @Primary
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 设置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(dataSource_me());
        // 配置多数据源
        Map<Object, Object> dsMap = new HashMap<>();
        dsMap.put("dataSource_me", dataSource_me());
        dsMap.put("dataSource_lse", dataSource_lse());

        dynamicDataSource.setTargetDataSources(dsMap);

        return dynamicDataSource;
    }

    /**
     * 配置@Transactional注解事物
     *
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }

    /**
     * 设置分页
     *
     * @return
     */
    @Bean
    public PageHelper pageHelper() {
        PageHelper pageHelper = new PageHelper();
        Properties p = new Properties();
        p.setProperty("offsetAsPageNum", "true");
        p.setProperty("rowBoundsWithCount", "true");
        p.setProperty("reasonable", "true");
        pageHelper.setProperties(p);
        return pageHelper;
    }


    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        //设置方言类型
        page.setDialectType("mysql");
        return page;
    }

    /**
     * 设置数据源公共参数
     *
     * @param dataSourceParams
     */
    public void setDataSourceParams(DruidDataSource dataSourceParams) {
        dataSourceParams.setInitialSize(Integer.parseInt(initialSize));
        dataSourceParams.setMinIdle(Integer.parseInt(minIdle));
        dataSourceParams.setMaxActive(Integer.parseInt(maxActive));
        dataSourceParams.setMaxWait(Long.parseLong(maxWait));
        dataSourceParams.setTimeBetweenEvictionRunsMillis(Long.parseLong(timeBetweenEvictionRunsMillis));
        dataSourceParams.setMinEvictableIdleTimeMillis(Long.parseLong(minEvictableIdleTimeMillis));
        dataSourceParams.setValidationQuery(validationQuery);
        dataSourceParams.setTestWhileIdle(Boolean.valueOf(testWhileIdle));
        dataSourceParams.setTestOnBorrow(Boolean.valueOf(testOnBorrow));
        dataSourceParams.setTestOnReturn(Boolean.valueOf(testOnReturn));
        dataSourceParams.setPoolPreparedStatements(Boolean.valueOf(poolPreparedStatements));
        dataSourceParams.setMaxPoolPreparedStatementPerConnectionSize(Integer.parseInt(maxPoolPreparedStatementPerConnectionSize));
        dataSourceParams.setConnectionProperties(connectionProperties);
    }

}
